import { loginUser, reqUserInfo, loginout } from '@/api/userInfo'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
import { constantRoutes, asyncIndeterminacyRoutes, AllloseRoute } from '@/router'
import { cloneDeep } from 'lodash'
import router from '@/router'
const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: '',
    routes: constantRoutes,
    rules: {}
  }
}
// 创建权限判定函数,用于判断该路由中是否含有不允许访问的地址并剔除
function filterRouter(allRoutes, rules) {
  return allRoutes.filter(item => {
    if (item.children?.length > 0) {
      // 由于是引用数据类型,导致直接修改children会影响到根数据,等到下次用户登录时,筛选的数据就会变少
      // 所以使用深拷贝修改数据
      item.children = filterRouter(item.children, rules)
    }
    return rules.some(el => item.name === el)
  })
}
const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
    setToken(token)
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_RULES: (state, rules) => {
    state.rules = rules
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ROUTES: (state, routes) => {
    state.routes = routes
  }
}

const actions = {
  // user login
  async login({ commit }, userInfo) {
    const { username, password } = userInfo
    let re = await loginUser(username, password)
    commit('SET_TOKEN', re.token)
  },

  // get user info
  async getInfo({ commit, state }) {
    try {
      let data = await reqUserInfo()
      const { name, avatar, ...rules } = data
      commit('SET_NAME', name)
      commit('SET_AVATAR', avatar)
      commit('SET_RULES', rules)
      let filterRouteList = filterRouter(cloneDeep(asyncIndeterminacyRoutes), rules.routes)
      // 添加404页面
      filterRouteList = filterRouteList.concat(AllloseRoute)
      // 调用函数更新路由表
      commit('SET_ROUTES', constantRoutes.concat(filterRouteList))
      // 并且更新路由对应关系,vueroute3中对应关系使用addRoutes([路由数组])直接添加
      router.addRoutes(filterRouteList.concat(AllloseRoute))
    } catch (error) {
      return Promise.reject(error)
    }
  },

  // user logout
  async logout({ commit, state }) {
    try {
      await loginout()
    } catch (error) {
      return Promise.reject(error)
    }
    removeToken() // must remove  token  first
    resetRouter()
    commit('RESET_STATE')
  },

  // remove token
  async resetToken({ commit }) {
    removeToken() // must remove  token  first
    commit('RESET_STATE')
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

